package org.iwidget.desktop.ui;
import org.iwidget.desktop.model.ElementScroller;
import org.iwidget.desktop.model.WidgetElement;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
/**
 *
 * @author Muhammad Hakim A
 */


public class WidgetScroller extends JComponent
    implements MouseListener, MouseMotionListener, KeyListener, DropTargetListener
{
    class ScrollThread extends Thread
    {

        public void run()
        {
            Point point = new Point(scrollData.getHScroller(), scrollData.getVScroller());
            boolean ended = false;
            int counter = 0;
            do
            {
                if(ended)
                    break;
                if(hDirection == 2)
                {
                    scrollData.setHScroller(scrollData.getHScroller() - 1);
                    if(scrollData.getHScroller() < 0)
                        scrollData.setHScroller(scrollData.getVWidth());
                }
                if(hDirection == 1)
                {
                    scrollData.setHScroller(scrollData.getHScroller() - 1);
                    if(scrollData.getHScroller() < scrollData.getVWidth() - scrollData.getWidth())
                        ended = true;
                }
                if(hDirection == -1)
                {
                    scrollData.setHScroller(scrollData.getHScroller() + 1);
                    if(scrollData.getHScroller() > scrollData.getVWidth() - scrollData.getWidth())
                        ended = true;
                }
                if(hDirection == -2)
                {
                    scrollData.setHScroller(scrollData.getHScroller() + 1);
                    if(scrollData.getHScroller() > scrollData.getVWidth())
                        scrollData.setHScroller(0);
                }
                try
                {
                    Thread.sleep(speed);
                }
                catch(Exception e) { }
                counter++;
                if(amount > 0 && counter > amount)
                    ended = true;
            } while(true);
            widget.triggerEvent("onScrollComplete");
        }

        JComponent parent;

        public ScrollThread(JComponent parent)
        {
            this.parent = parent;
        }
    }


    public WidgetScroller(WidgetElement widget, ElementScroller scrollData)
    {
        amount = 0;
        hDirection = 0;
        vDirection = 0;
        this.widget = widget;
        this.scrollData = scrollData;
        setBackground(new Color(0, 0, 0, 0));
        setOpaque(true);
        setSize(scrollData.getWidth(), scrollData.getHeight());
        setLocation(scrollData.getX(), scrollData.getY());
        setDoubleBuffered(true);
        p = new JPanel();
        p.setPreferredSize(new Dimension(scrollData.getVWidth(), scrollData.getVHeight()));
        p.setBackground(getBGColorObject());
        p.setLayout(null);
        p.setDoubleBuffered(true);
        scroller = new JScrollPane();
        scroller.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
        scroller.setBackground(new Color(0, 0, 0, 0));
        scroller.setDoubleBuffered(true);
        scroller.setSize(scrollData.getWidth(), scrollData.getHeight());
        scroller.getViewport().setBackground(new Color(0, 0, 0, 0));
        scroller.getViewport().add(p);
        scroller.setHorizontalScrollBarPolicy(31);
        scroller.setVerticalScrollBarPolicy(21);
        scroller.getViewport().setBackingStoreEnabled(true);
        add(scroller);
        scrollData.setUIComponent(this);
        startScrolling(scrollData.getScrollSpeed(), scrollData.getHDirection(), 0);
        setVisible(true);
        setVSize(scrollData.getVWidth(), scrollData.getVHeight());
        scroller.addMouseListener(this);
        scroller.addMouseMotionListener(this);
        scroller.addKeyListener(this);
    }

    public Color getBGColorObject()
    {
        if(scrollData.getBgColor().startsWith("#") && scrollData.getBgColor().length() == 7)
        {
            int intColor = Integer.decode(scrollData.getBgColor()).intValue();
            Color c = new Color(intColor, true);
            float masterOpacity = (float)widget.getWindowJS().getOpacity() / 100F;
            masterOpacity *= (float)scrollData.getBgOpacity() / 100F;
            return new Color(c.getRed(), c.getGreen(), c.getBlue(), (int)(255F * masterOpacity));
        } else
        {
            return Color.WHITE;
        }
    }

    public void paintComponent(Graphics g)
    {
        if(!scrollData.getVisible())
        {
            return;
        } else
        {
            super.paintComponent(g);
            return;
        }
    }

    public void setColor()
    {
        p.setBackground(getBGColorObject());
    }

    public void addWidgetImage(WidgetImage element)
    {
        p.add(element);
    }

    public void addWidgetText(WidgetText element)
    {
        p.add(element);
    }

    public void addWidgetTextArea(WidgetTextArea element)
    {
        p.add(element);
    }

    public void setVSize(int width, int height)
    {
        p.setPreferredSize(new Dimension(width, height));
        p.setSize(new Dimension(width, height));
    }

    public int getHScroller()
    {
        return scroller.getViewport().getViewPosition().x;
    }

    public void setHScroller(int x)
    {
        scroller.getViewport().setViewPosition(new Point(x, scrollData.getVScroller()));
    }

    public int getVScroller()
    {
        return scroller.getViewport().getViewPosition().y;
    }

    public void setVScroller(int y)
    {
        scroller.getViewport().setViewPosition(new Point(getHScroller(), y));
    }

    public void stopScrolling()
    {
        if(t != null && t.isAlive())
        {
            t.stop();
            t = null;
        }
    }

    public void startScrolling()
    {
        startScrolling(speed, hDirection, vDirection);
    }

    public void startScrolling(int speed, int hDirection, int vDirection)
    {
        if(t != null && t.isAlive())
        {
            t.stop();
            t = null;
        }
        this.speed = speed;
        this.hDirection = hDirection;
        this.vDirection = vDirection;
        if(hDirection != 0 || vDirection != 0)
        {
            t = new ScrollThread(this);
            t.setPriority(1);
            t.start();
        }
    }

    public void startScrolling(int speed, int hDirection, int vDirection, int amount)
    {
        this.amount = amount;
        startScrolling(speed, hDirection, vDirection);
    }

    public void mousePressed(MouseEvent e)
    {
        if(e.getButton() != 3)
        {
            scrollData.triggerEvent("onMouseDown");
            widget.getUIComponent().mousePressed(e);
        }
    }

    public void mouseReleased(MouseEvent e)
    {
        if(e.getButton() != 3)
        {
            scrollData.triggerEvent("onMouseUp");
            widget.getUIComponent().mouseReleased(e);
        } else
        {
            widget.getUIComponent().showContextMenu();
        }
    }

    public void mouseEntered(MouseEvent e)
    {
        scrollData.triggerEvent("onMouseEnter");
    }

    public void mouseExited(MouseEvent e)
    {
        scrollData.triggerEvent("onMouseExit");
    }

    public void mouseMoved(MouseEvent mouseevent)
    {
    }

    public void mouseClicked(MouseEvent mouseevent)
    {
    }

    public void mouseDragged(MouseEvent e)
    {
        widget.getUIComponent().mouseDragged(e);
    }

    public void keyTyped(KeyEvent e)
    {
        scrollData.triggerEvent("onKeyPress");
    }

    public void keyPressed(KeyEvent e)
    {
        widget.getIwidgetData().key = e.getKeyChar();
        widget.getIwidgetData().keyString = KeyEvent.getKeyText(e.getKeyCode());
        widget.getIwidgetData().keyModifiers = KeyEvent.getKeyModifiersText(e.getModifiers());
        scrollData.triggerEvent("onKeyDown");
    }

    public void keyReleased(KeyEvent e)
    {
        widget.getIwidgetData().key = e.getKeyChar();
        widget.getIwidgetData().keyString = KeyEvent.getKeyText(e.getKeyCode());
        widget.getIwidgetData().keyModifiers = KeyEvent.getKeyModifiersText(e.getModifiers());
        scrollData.triggerEvent("onKeyUp");
    }

    public void dragOver(DropTargetDragEvent droptargetdragevent)
    {
    }

    public void dragActionChanged(DropTargetDragEvent droptargetdragevent)
    {
    }

    public void dropActionChanged(DropTargetDragEvent droptargetdragevent)
    {
    }

    public void dragEnter(DropTargetDragEvent e)
    {
        System.out.println("DragEnter");
        scrollData.triggerEvent("onDragEnter");
    }

    public void dragExit(DropTargetEvent e)
    {
        System.out.println("DragExit");
        scrollData.triggerEvent("onDragExit");
    }

    public void drop(DropTargetDropEvent e)
    {
        System.out.println("DragDrop");
        try
        {
            Transferable tr = e.getTransferable();
            if(tr.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
            {
                e.acceptDrop(3);
                ArrayList dropFiles = new ArrayList();
                ArrayList dropDirs = new ArrayList();
                java.util.List fileList = (java.util.List)tr.getTransferData(DataFlavor.javaFileListFlavor);
                for(Iterator iterator = fileList.iterator(); iterator.hasNext();)
                {
                    File file = (File)iterator.next();
                    if(file.isDirectory())
                        dropDirs.add(file.getAbsolutePath());
                    else
                        dropFiles.add(file.getAbsolutePath());
                }

                e.getDropTargetContext().dropComplete(true);
                String dropFilesArray[] = new String[dropFiles.size()];
                for(int iCtr = 0; iCtr < dropFiles.size(); iCtr++)
                    dropFilesArray[iCtr] = (String)dropFiles.get(iCtr);

                widget.getIwidgetData().droppedObjects = dropFilesArray;
                widget.getIwidgetData().droppedObjectsType = "filenames";
                scrollData.triggerEvent("onDragDrop");
            } else
            if(tr.isDataFlavorSupported(DataFlavor.stringFlavor))
            {
                e.acceptDrop(3);
                String url = (String)tr.getTransferData(DataFlavor.stringFlavor);
                if(url.toLowerCase().startsWith("http:") || url.toLowerCase().startsWith("https:") || url.toLowerCase().startsWith("ftp:"))
                {
                    String dropUrl[] = {
                        url
                    };
                    widget.getIwidgetData().droppedObjects = dropUrl;
                    widget.getIwidgetData().droppedObjectsType = "url";
                    e.getDropTargetContext().dropComplete(true);
                    scrollData.triggerEvent("onDragDrop");
                } else
                {
                    e.rejectDrop();
                }
            } else
            {
                System.err.println("Rejected");
                e.rejectDrop();
            }
        }
        catch(IOException io)
        {
            io.printStackTrace();
            e.rejectDrop();
        }
        catch(UnsupportedFlavorException ufe)
        {
            ufe.printStackTrace();
            e.rejectDrop();
        }
    }

    private static final long serialVersionUID = 0x3733343634353038L;
    private WidgetElement widget;
    private ElementScroller scrollData;
    private JScrollPane scroller;
    private JPanel p;
    public ScrollThread t;
    private int speed;
    private int amount;
    private int hDirection;
    private int vDirection;
    Image img;

}